<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>

<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.33">

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">


<title>2&nbsp; Control flow, structs, modules and types – Introduction to Zig</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
  width: 0.8em;
  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
  vertical-align: middle;
}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
</style>


<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
<script src="../site_libs/quarto-nav/headroom.min.js"></script>
<script src="../site_libs/clipboard/clipboard.min.js"></script>
<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
<script src="../site_libs/quarto-search/fuse.min.js"></script>
<script src="../site_libs/quarto-search/quarto-search.js"></script>
<meta name="quarto:offset" content="../">
<link href="../Chapters/01-memory.html" rel="next">
<link href="../Chapters/01-zig-weird.html" rel="prev">
<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../site_libs/quarto-html/popper.min.js"></script>
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../site_libs/quarto-html/anchor.min.js"></script>
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-59898bd1c6b9d2bb783127feaa000c76.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-dark-d329e753491efaeac79c98c4b193a686.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-59898bd1c6b9d2bb783127feaa000c76.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../site_libs/bootstrap/bootstrap-5a7d69291c2a8c67bc3a157f4354e263.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../site_libs/bootstrap/bootstrap-dark-a459d9a911ec262923466a12d18bc01e.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../site_libs/bootstrap/bootstrap-5a7d69291c2a8c67bc3a157f4354e263.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
  "location": "sidebar",
  "copy-button": false,
  "collapse-after": 3,
  "panel-placement": "start",
  "type": "textbox",
  "limit": 50,
  "keyboard-shortcut": [
    "f",
    "/",
    "s"
  ],
  "show-item-context": false,
  "language": {
    "search-no-results-text": "No results",
    "search-matching-documents-text": "matching documents",
    "search-copy-link-title": "Copy link to search",
    "search-hide-matches-text": "Hide additional matches",
    "search-more-match-text": "more match in this document",
    "search-more-matches-text": "more matches in this document",
    "search-clear-button-title": "Clear",
    "search-text-placeholder": "",
    "search-detached-cancel-button-title": "Cancel",
    "search-submit-button-title": "Submit",
    "search-label": "Search"
  }
}</script>
<script async="" src="https://www.googletagmanager.com/gtag/js?id=G-6CHJXK4CEV"></script>

<script type="text/javascript">

window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-6CHJXK4CEV', { 'anonymize_ip': true});
</script>


</head>

<body class="nav-sidebar floating quarto-light"><script id="quarto-html-before-body" type="application/javascript">
    const toggleBodyColorMode = (bsSheetEl) => {
      const mode = bsSheetEl.getAttribute("data-mode");
      const bodyEl = window.document.querySelector("body");
      if (mode === "dark") {
        bodyEl.classList.add("quarto-dark");
        bodyEl.classList.remove("quarto-light");
      } else {
        bodyEl.classList.add("quarto-light");
        bodyEl.classList.remove("quarto-dark");
      }
    }
    const toggleBodyColorPrimary = () => {
      const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])");
      if (bsSheetEl) {
        toggleBodyColorMode(bsSheetEl);
      }
    }
    const setColorSchemeToggle = (alternate) => {
      const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
      for (let i=0; i < toggles.length; i++) {
        const toggle = toggles[i];
        if (toggle) {
          if (alternate) {
            toggle.classList.add("alternate");
          } else {
            toggle.classList.remove("alternate");
          }
        }
      }
    };
    const toggleColorMode = (alternate) => {
      // Switch the stylesheets
      const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)');
      const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
      manageTransitions('#quarto-margin-sidebar .nav-link', false);
      if (alternate) {
        // note: dark is layered on light, we don't disable primary!
        enableStylesheet(alternateStylesheets);
        for (const sheetNode of alternateStylesheets) {
          if (sheetNode.id === "quarto-bootstrap") {
            toggleBodyColorMode(sheetNode);
          }
        }
      } else {
        disableStylesheet(alternateStylesheets);
        enableStylesheet(primaryStylesheets)
        toggleBodyColorPrimary();
      }
      manageTransitions('#quarto-margin-sidebar .nav-link', true);
      // Switch the toggles
      setColorSchemeToggle(alternate)
      // Hack to workaround the fact that safari doesn't
      // properly recolor the scrollbar when toggling (#1455)
      if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
        manageTransitions("body", false);
        window.scrollTo(0, 1);
        setTimeout(() => {
          window.scrollTo(0, 0);
          manageTransitions("body", true);
        }, 40);
      }
    }
    const disableStylesheet = (stylesheets) => {
      for (let i=0; i < stylesheets.length; i++) {
        const stylesheet = stylesheets[i];
        stylesheet.rel = 'disabled-stylesheet';
      }
    }
    const enableStylesheet = (stylesheets) => {
      for (let i=0; i < stylesheets.length; i++) {
        const stylesheet = stylesheets[i];
        if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check
          stylesheet.rel = 'stylesheet';
        }
      }
    }
    const manageTransitions = (selector, allowTransitions) => {
      const els = window.document.querySelectorAll(selector);
      for (let i=0; i < els.length; i++) {
        const el = els[i];
        if (allowTransitions) {
          el.classList.remove('notransition');
        } else {
          el.classList.add('notransition');
        }
      }
    }
    const isFileUrl = () => {
      return window.location.protocol === 'file:';
    }
    const hasAlternateSentinel = () => {
      let styleSentinel = getColorSchemeSentinel();
      if (styleSentinel !== null) {
        return styleSentinel === "alternate";
      } else {
        return false;
      }
    }
    const setStyleSentinel = (alternate) => {
      const value = alternate ? "alternate" : "default";
      if (!isFileUrl()) {
        window.localStorage.setItem("quarto-color-scheme", value);
      } else {
        localAlternateSentinel = value;
      }
    }
    const getColorSchemeSentinel = () => {
      if (!isFileUrl()) {
        const storageValue = window.localStorage.getItem("quarto-color-scheme");
        return storageValue != null ? storageValue : localAlternateSentinel;
      } else {
        return localAlternateSentinel;
      }
    }
    const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
      const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
      const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
      let newTheme = '';
      if(authorPrefersDark) {
        newTheme = isAlternate ? baseTheme : alternateTheme;
      } else {
        newTheme = isAlternate ? alternateTheme : baseTheme;
      }
      const changeGiscusTheme = () => {
        // From: https://github.com/giscus/giscus/issues/336
        const sendMessage = (message) => {
          const iframe = document.querySelector('iframe.giscus-frame');
          if (!iframe) return;
          iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
        }
        sendMessage({
          setConfig: {
            theme: newTheme
          }
        });
      }
      const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
      if (isGiscussLoaded) {
        changeGiscusTheme();
      }
    };
    const authorPrefersDark = false;
    const darkModeDefault = authorPrefersDark;
      document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
      document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
    let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
    // Dark / light mode switch
    window.quartoToggleColorScheme = () => {
      // Read the current dark / light value
      let toAlternate = !hasAlternateSentinel();
      toggleColorMode(toAlternate);
      setStyleSentinel(toAlternate);
      toggleGiscusIfUsed(toAlternate, darkModeDefault);
      window.dispatchEvent(new Event('resize'));
    };
    // Switch to dark mode if need be
    if (hasAlternateSentinel()) {
      toggleColorMode(true);
    } else {
      toggleColorMode(false);
    }
  </script>

<div id="quarto-search-results"></div>
  <header id="quarto-header" class="headroom fixed-top">
  <nav class="quarto-secondary-nav">
    <div class="container-fluid d-flex">
      <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" role="button" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
        <i class="bi bi-layout-text-sidebar-reverse"></i>
      </button>
        <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="../Chapters/03-structs.html"><span class="chapter-number">2</span>&nbsp; <span class="chapter-title">Control flow, structs, modules and types</span></a></li></ol></nav>
        <a class="flex-grow-1" role="navigation" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">      
        </a>
      <button type="button" class="btn quarto-search-button" aria-label="Search" onclick="window.quartoOpenSearch();">
        <i class="bi bi-search"></i>
      </button>
    </div>
  </nav>
</header>
<!-- content -->
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
<!-- sidebar -->
  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto">
    <div class="pt-lg-2 mt-2 text-left sidebar-header">
    <div class="sidebar-title mb-0 py-0">
      <a href="../">Introduction to Zig</a> 
        <div class="sidebar-tools-main">
  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
</div>
    </div>
      </div>
        <div class="mt-2 flex-shrink-0 align-items-center">
        <div class="sidebar-search">
        <div id="quarto-search" class="" title="Search"></div>
        </div>
        </div>
    <div class="sidebar-menu-container"> 
    <ul class="list-unstyled mt-1">
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../index.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Welcome</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-zig-weird.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">1</span>&nbsp; <span class="chapter-title">Introducing Zig</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/03-structs.html" class="sidebar-item-text sidebar-link active">
 <span class="menu-text"><span class="chapter-number">2</span>&nbsp; <span class="chapter-title">Control flow, structs, modules and types</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-memory.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">3</span>&nbsp; <span class="chapter-title">Memory and Allocators</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-base64.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">4</span>&nbsp; <span class="chapter-title">Project 1 - Building a base64 encoder/decoder</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/02-debugging.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">5</span>&nbsp; <span class="chapter-title">Debugging Zig applications</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/05-pointers.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">6</span>&nbsp; <span class="chapter-title">Pointers and Optionals</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/04-http-server.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">7</span>&nbsp; <span class="chapter-title">Project 2 - Building a HTTP Server from scratch</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/03-unittests.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">8</span>&nbsp; <span class="chapter-title">Unit tests</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/07-build-system.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">9</span>&nbsp; <span class="chapter-title">Build System</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/09-error-handling.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">10</span>&nbsp; <span class="chapter-title">Error handling and unions</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/09-data-structures.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">11</span>&nbsp; <span class="chapter-title">Data Structures</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/10-stack-project.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">12</span>&nbsp; <span class="chapter-title">Project 3 - Building a stack data structure</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/12-file-op.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">13</span>&nbsp; <span class="chapter-title">Filesystem and Input/Output (IO)</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/14-zig-c-interop.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">14</span>&nbsp; <span class="chapter-title">Zig interoperability with C</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/13-image-filter.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">15</span>&nbsp; <span class="chapter-title">Project 4 - Developing an image filter</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/14-threads.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">16</span>&nbsp; <span class="chapter-title">Introducing threads and parallelism in Zig</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/15-vectors.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">17</span>&nbsp; <span class="chapter-title">Introducing Vectors and SIMD</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/references.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">References</span></a>
  </div>
</li>
    </ul>
    </div>
</nav>
<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
<!-- margin-sidebar -->
    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
        <nav id="TOC" role="doc-toc" class="toc-active">
    <h2 id="toc-title">Table of contents</h2>
   
  <ul>
  <li><a href="#sec-zig-control-flow" id="toc-sec-zig-control-flow" class="nav-link active" data-scroll-target="#sec-zig-control-flow"><span class="header-section-number">2.1</span> Control flow</a>
  <ul class="collapse">
  <li><a href="#ifelse-statements" id="toc-ifelse-statements" class="nav-link" data-scroll-target="#ifelse-statements"><span class="header-section-number">2.1.1</span> If/else statements</a></li>
  <li><a href="#sec-switch" id="toc-sec-switch" class="nav-link" data-scroll-target="#sec-switch"><span class="header-section-number">2.1.2</span> Switch statements</a></li>
  <li><a href="#sec-defer" id="toc-sec-defer" class="nav-link" data-scroll-target="#sec-defer"><span class="header-section-number">2.1.3</span> The <code>defer</code> keyword</a></li>
  <li><a href="#sec-errdefer1" id="toc-sec-errdefer1" class="nav-link" data-scroll-target="#sec-errdefer1"><span class="header-section-number">2.1.4</span> The <code>errdefer</code> keyword</a></li>
  <li><a href="#for-loops" id="toc-for-loops" class="nav-link" data-scroll-target="#for-loops"><span class="header-section-number">2.1.5</span> For loops</a></li>
  <li><a href="#while-loops" id="toc-while-loops" class="nav-link" data-scroll-target="#while-loops"><span class="header-section-number">2.1.6</span> While loops</a></li>
  <li><a href="#using-break-and-continue" id="toc-using-break-and-continue" class="nav-link" data-scroll-target="#using-break-and-continue"><span class="header-section-number">2.1.7</span> Using <code>break</code> and <code>continue</code></a></li>
  </ul></li>
  <li><a href="#sec-fun-pars" id="toc-sec-fun-pars" class="nav-link" data-scroll-target="#sec-fun-pars"><span class="header-section-number">2.2</span> Function parameters are immutable</a>
  <ul class="collapse">
  <li><a href="#a-free-optimization" id="toc-a-free-optimization" class="nav-link" data-scroll-target="#a-free-optimization"><span class="header-section-number">2.2.1</span> A free optimization</a></li>
  <li><a href="#how-to-overcome-this-barrier" id="toc-how-to-overcome-this-barrier" class="nav-link" data-scroll-target="#how-to-overcome-this-barrier"><span class="header-section-number">2.2.2</span> How to overcome this barrier</a></li>
  </ul></li>
  <li><a href="#sec-structs-and-oop" id="toc-sec-structs-and-oop" class="nav-link" data-scroll-target="#sec-structs-and-oop"><span class="header-section-number">2.3</span> Structs and OOP</a>
  <ul class="collapse">
  <li><a href="#the-pub-keyword" id="toc-the-pub-keyword" class="nav-link" data-scroll-target="#the-pub-keyword"><span class="header-section-number">2.3.1</span> The <code>pub</code> keyword</a></li>
  <li><a href="#sec-anonymous-struct-literals" id="toc-sec-anonymous-struct-literals" class="nav-link" data-scroll-target="#sec-anonymous-struct-literals"><span class="header-section-number">2.3.2</span> Anonymous struct literals</a></li>
  <li><a href="#struct-declarations-must-be-constant" id="toc-struct-declarations-must-be-constant" class="nav-link" data-scroll-target="#struct-declarations-must-be-constant"><span class="header-section-number">2.3.3</span> Struct declarations must be constant</a></li>
  <li><a href="#sec-self-arg" id="toc-sec-self-arg" class="nav-link" data-scroll-target="#sec-self-arg"><span class="header-section-number">2.3.4</span> The <code>self</code> method argument</a></li>
  <li><a href="#about-the-struct-state" id="toc-about-the-struct-state" class="nav-link" data-scroll-target="#about-the-struct-state"><span class="header-section-number">2.3.5</span> About the struct state</a></li>
  </ul></li>
  <li><a href="#sec-type-inference" id="toc-sec-type-inference" class="nav-link" data-scroll-target="#sec-type-inference"><span class="header-section-number">2.4</span> Type inference</a></li>
  <li><a href="#sec-type-cast" id="toc-sec-type-cast" class="nav-link" data-scroll-target="#sec-type-cast"><span class="header-section-number">2.5</span> Type casting</a></li>
  <li><a href="#modules" id="toc-modules" class="nav-link" data-scroll-target="#modules"><span class="header-section-number">2.6</span> Modules</a></li>
  </ul>
</nav>
    </div>
<!-- main -->
<main class="content" id="quarto-document-content">


<header id="title-block-header" class="quarto-title-block default">
<div class="quarto-title">
<h1 class="title"><span class="chapter-number">2</span>&nbsp; <span class="chapter-title">Control flow, structs, modules and types</span></h1>
</div>



<div class="quarto-title-meta">

    
  
    
  </div>
  


</header>


<p>We have discussed a lot of Zig’s syntax in the last chapter, especially in <a href="01-zig-weird.html#sec-root-file" class="quarto-xref"><span>Section 1.2.2</span></a> and <a href="01-zig-weird.html#sec-main-file" class="quarto-xref"><span>Section 1.2.3</span></a>. But we still need to discuss some other very important elements of the language. Elements that you will use constantly on your day-to-day routine.</p>
<p>We begin this chapter by discussing the different keywords and structures in Zig related to control flow (e.g.&nbsp;loops and if statements). Then, we talk about structs and how they can be used to do some basic Object-Oriented (OOP) patterns in Zig. We also talk about type inference and type casting. Finally, we end this chapter by discussing modules, and how they relate to structs.</p>
<section id="sec-zig-control-flow" class="level2" data-number="2.1">
<h2 data-number="2.1" class="anchored" data-anchor-id="sec-zig-control-flow"><span class="header-section-number">2.1</span> Control flow</h2>
<p>Sometimes, you need to make decisions in your program. Maybe you need to decide whether or not to execute a specific piece of code. Or maybe, you need to apply the same operation over a sequence of values. These kinds of tasks, involve using structures that are capable of changing the “control flow” of our program.</p>
<p>In computer science, the term “control flow” usually refers to the order in which expressions (or commands) are evaluated in a given language or program. But this term is also used to refer to structures that are capable of changing this “evaluation order” of the commands executed by a given language/program.</p>
<p>These structures are better known by a set of terms, such as: loops, if/else statements, switch statements, among others. So, loops and if/else statements are examples of structures that can change the “control flow” of our program. The keywords <code>continue</code> and <code>break</code> are also examples of symbols that can change the order of evaluation, since they can move our program to the next iteration of a loop, or make the loop stop completely.</p>
<section id="ifelse-statements" class="level3" data-number="2.1.1">
<h3 data-number="2.1.1" class="anchored" data-anchor-id="ifelse-statements"><span class="header-section-number">2.1.1</span> If/else statements</h3>
<p>An if/else statement performs a “conditional flow operation”. A conditional flow control (or choice control) allows you to execute or ignore a certain block of commands based on a logical condition. Many programmers and computer science professionals also use the term “branching” in this case. In essence, an if/else statement allow us to use the result of a logical test to decide whether or not to execute a given block of commands.</p>
<p>In Zig, we write if/else statements by using the keywords <code>if</code> and <code>else</code>. We start with the <code>if</code> keyword followed by a logical test inside a pair of parentheses, followed by a pair of curly braces which contains the lines of code to be executed in case the logical test returns the value <code>true</code>.</p>
<p>After that, you can optionally add an <code>else</code> statement. To do that, just add the <code>else</code> keyword followed by a pair of curly braces, with the lines of code to executed in case the logical test defined at <code>if</code> returns <code>false</code>.</p>
<p>In the example below, we are testing if the object <code>x</code> contains a number that is greater than 10. Judging by the output printed to the console, we know that this logical test returned <code>false</code>. Because the output in the console is compatible with the line of code present in the <code>else</code> branch of the if/else statement.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb1"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> x = <span class="dv">5</span>;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">if</span> (x &gt; <span class="dv">10</span>) <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"x &gt; 10!</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span>);</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="kw">else</span> <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"x &lt;= 10!</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span>);</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>x &lt;= 10!</code></pre>
</div>
</div>
</section>
<section id="sec-switch" class="level3" data-number="2.1.2">
<h3 data-number="2.1.2" class="anchored" data-anchor-id="sec-switch"><span class="header-section-number">2.1.2</span> Switch statements</h3>
<p>Switch statements are also available in Zig, and they have a very similar syntax to a switch statement in Rust. As you would expect, to write a switch statement in Zig we use the <code>switch</code> keyword. We provide the value that we want to “switch over” inside a pair of parentheses. Then, we list the possible combinations (or “branches”) inside a pair of curly braces.</p>
<p>Let’s take a look at the code example below. You can see that I’m creating an enum type called <code>Role</code>. We talk more about enums in <a href="04-http-server.html#sec-enum" class="quarto-xref"><span>Section 7.6</span></a>. But in summary, this <code>Role</code> type is listing different types of roles in a fictitious company, like <code>SE</code> for Software Engineer, <code>DE</code> for Data Engineer, <code>PM</code> for Product Manager, etc.</p>
<p>Notice that we are using the value from the <code>role</code> object in the switch statement, to discover which exact area we need to store in the <code>area</code> variable object. Also notice that we are using type inference inside the switch statement, with the dot character, as we are going to describe in <a href="#sec-type-inference" class="quarto-xref"><span>Section 2.4</span></a>. This makes the <code>zig</code> compiler infer the correct data type of the values (<code>PM</code>, <code>SE</code>, etc.) for us.</p>
<p>Also notice that, we are grouping multiple values in the same branch of the switch statement. We just separate each possible value with a comma. For example, if <code>role</code> contains either <code>DE</code> or <code>DA</code>, the <code>area</code> variable would contain the value <code>"Data &amp; Analytics"</code>, instead of <code>"Platform"</code> or <code>"Sales"</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb3"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_buffer: [<span class="dv">1024</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_writer = std.fs.File.stdout().writer(&amp;stdout_buffer);</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> stdout = &amp;stdout_writer.interface;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Role = <span class="kw">enum</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    SE, DPE, DE, DA, PM, PO, KS</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> area: []<span class="kw">const</span> <span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> role = Role.SE;</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> (role) <span class="op">{</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>        .PM, .SE, .DPE, .PO =&gt; <span class="op">{</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>            area = <span class="st">"Platform"</span>;</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>,</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>        .DE, .DA =&gt; <span class="op">{</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>            area = <span class="st">"Data &amp; Analytics"</span>;</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>,</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>        .KS =&gt; <span class="op">{</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>            area = <span class="st">"Sales"</span>;</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>,</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{s}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>area<span class="op">}</span>);</span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.flush();</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>Platform</code></pre>
</div>
</div>
<section id="switch-statements-must-exhaust-all-possibilities" class="level4" data-number="2.1.2.1">
<h4 data-number="2.1.2.1" class="anchored" data-anchor-id="switch-statements-must-exhaust-all-possibilities"><span class="header-section-number">2.1.2.1</span> Switch statements must exhaust all possibilities</h4>
<p>One very important aspect about switch statements in Zig is that they must exhaust all existing possibilities. In other words, all possible values that could be found inside the <code>role</code> object must be explicitly handled in this switch statement.</p>
<p>Since the <code>role</code> object has type <code>Role</code>, the only possible values to be found inside this object are <code>PM</code>, <code>SE</code>, <code>DPE</code>, <code>PO</code>, <code>DE</code>, <code>DA</code> and <code>KS</code>. There are no other possible values to be stored in this <code>role</code> object. Thus, the switch statements must have a combination (branch) for each one of these values. This is what “exhaust all existing possibilities” means. The switch statement covers every possible case.</p>
<p>Therefore, you cannot write a switch statement in Zig, and leave an edge case with no explicit action to be taken. This is a similar behaviour to switch statements in Rust, which also have to handle all possible cases.</p>
</section>
<section id="the-else-branch" class="level4" data-number="2.1.2.2">
<h4 data-number="2.1.2.2" class="anchored" data-anchor-id="the-else-branch"><span class="header-section-number">2.1.2.2</span> The else branch</h4>
<p>Take a look at the <code>dump_hex_fallible()</code> function below as an example. This function comes from the Zig Standard Library. More precisely, from the <a href="https://github.com/ziglang/zig/blob/master/lib/std/debug.zig"><code>debug.zig</code> module</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>. There are multiple lines in this function, but I omitted them to focus solely on the switch statement found in this function. Notice that this switch statement has four possible cases (i.e., four explicit branches). Also, notice that we used an <code>else</code> branch in this case.</p>
<p>An <code>else</code> branch in a switch statement works as the “default branch”. Whenever you have multiple cases in your switch statement where you want to apply the exact same action, you can use an <code>else</code> branch to do that.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb5"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> dump_hex_fallible(bytes: []<span class="kw">const</span> <span class="dt">u8</span>) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Many lines ...</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> (byte) <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        <span class="ch">'\n'</span> =&gt; <span class="kw">try</span> writer.writeAll(<span class="st">"␊"</span>),</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="ch">'\r'</span> =&gt; <span class="kw">try</span> writer.writeAll(<span class="st">"␍"</span>),</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        <span class="ch">'\t'</span> =&gt; <span class="kw">try</span> writer.writeAll(<span class="st">"␉"</span>),</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span> =&gt; <span class="kw">try</span> writer.writeByte(<span class="ch">'.'</span>),</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Many programmers would also use an <code>else</code> branch to handle a “not supported” case. That is, a case that cannot be properly handled by your code, or, just a case that should not be “fixed”. Therefore, you can use an <code>else</code> branch to panic (or raise an error) in your program to stop the current execution.</p>
<p>Take the code example below. We can see that, we are handling the cases for the <code>level</code> object being either 1, 2, or 3. All other possible cases are not supported by default, and, as consequence, we raise a runtime error in such cases through the <code>@panic()</code> built-in function.</p>
<p>Also notice that, we are assigning the result of the switch statement to a new object called <code>category</code>. This is another thing that you can do with switch statements in Zig. If a branch outputs a value as result, you can store the result value of the switch statement into a new object.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb6"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> level: <span class="dt">u8</span> = <span class="dv">4</span>;</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> category = <span class="kw">switch</span> (level) <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span>, <span class="dv">2</span> =&gt; <span class="st">"beginner"</span>,</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> =&gt; <span class="st">"professional"</span>,</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> =&gt; <span class="op">{</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        <span class="bu">@panic</span>(<span class="st">"Not supported level!"</span>);</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>,</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.print(<span class="st">"{s}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>category<span class="op">}</span>);</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>thread 13103 panic: Not supported level!
t.zig:9:13: 0x1033c58 in main (switch2)
            @panic("Not supported level!");
            ^</code></pre>
</section>
<section id="using-ranges-in-switch" class="level4" data-number="2.1.2.3">
<h4 data-number="2.1.2.3" class="anchored" data-anchor-id="using-ranges-in-switch"><span class="header-section-number">2.1.2.3</span> Using ranges in switch</h4>
<p>Furthermore, you can also use ranges of values in switch statements. That is, you can create a branch in your switch statement that is used whenever the input value is within the specified range. These “range expressions” are created with the operator <code>...</code>. It’s important to emphasize that the ranges created by this operator are inclusive on both ends.</p>
<p>For example, I could easily change the previous code example to support all levels between 0 and 100. Like this:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb8"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> level: <span class="dt">u8</span> = <span class="dv">4</span>;</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> category = <span class="kw">switch</span> (level) <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span>...<span class="dv">25</span> =&gt; <span class="st">"beginner"</span>,</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="dv">26</span>...<span class="dv">75</span> =&gt; <span class="st">"intermediary"</span>,</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="dv">76</span>...<span class="dv">100</span> =&gt; <span class="st">"professional"</span>,</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> =&gt; <span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        <span class="bu">@panic</span>(<span class="st">"Not supported level!"</span>);</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>,</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.print(<span class="st">"{s}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>category<span class="op">}</span>);</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>beginner</code></pre>
</div>
</div>
<p>This is neat, and it works with character ranges too. That is, I could simply write <code>'a'...'z'</code>, to match any character value that is a lowercase letter, and it would work fine.</p>
</section>
<section id="labeled-switch-statements" class="level4" data-number="2.1.2.4">
<h4 data-number="2.1.2.4" class="anchored" data-anchor-id="labeled-switch-statements"><span class="header-section-number">2.1.2.4</span> Labeled switch statements</h4>
<p>In <a href="01-zig-weird.html#sec-blocks" class="quarto-xref"><span>Section 1.7</span></a> we have talked about labeling blocks, and also, about using these labels to return a value from the block. Well, from version 0.14.0 and onwards of the <code>zig</code> compiler, you can also apply labels over switch statements, which makes it possible to almost implement a “C <code>goto</code>” like pattern.</p>
<p>For example, if you give the label <code>xsw</code> to a switch statement, you can use this label in conjunction with the <code>continue</code> keyword to go back to the beginning of the switch statement. In the example below, the execution goes back to the beginning of the switch statement two times, before ending at the <code>3</code> branch.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb10"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>xsw: <span class="kw">switch</span> (<span class="bu">@as</span>(<span class="dt">u8</span>, <span class="dv">1</span>)) <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span> =&gt; <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">try</span> stdout.print(<span class="st">"First branch</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span>);</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">continue</span> :xsw <span class="dv">2</span>;</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>,</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span> =&gt; <span class="kw">continue</span> :xsw <span class="dv">3</span>,</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> =&gt; <span class="kw">return</span>,</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    <span class="dv">4</span> =&gt; <span class="op">{}</span>,</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> =&gt; <span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">try</span> stdout.print(</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>            <span class="st">"Unmatched case, value: {d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span><span class="bu">@as</span>(<span class="dt">u8</span>, <span class="dv">1</span>)<span class="op">}</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>        );</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">try</span> stdout.flush();</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>,</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
</section>
</section>
<section id="sec-defer" class="level3" data-number="2.1.3">
<h3 data-number="2.1.3" class="anchored" data-anchor-id="sec-defer"><span class="header-section-number">2.1.3</span> The <code>defer</code> keyword</h3>
<p>Zig has a <code>defer</code> keyword, which plays a very important role in control flow, and also, in releasing resources. In summary, the <code>defer</code> keyword allows you to register an expression to be executed when you exit the current scope.</p>
<p>At this point, you might attempt to compare the Zig <code>defer</code> keyword to it’s sibling in the Go language (i.e.&nbsp;<a href="https://go.dev/tour/flowcontrol/12">Go also has a <code>defer</code> keyword</a>). However, the Go <code>defer</code> keyword behaves slightly different than it’s sibling in Zig. More specifically, the <code>defer</code> keyword in Go always move an expression to be executed at the <strong>exit of the current function</strong>.</p>
<p>If you think deeply about this statement, you will notice that the “exit of the current function” is something slightly different than the “exit of the current scope”. So, just be careful when comparing the two keywords together. A single function in Zig might contain many different scopes inside of it, and, therefore, the <code>defer</code> input expression might be executed at different places of the function, depending on which scope you are currently in.</p>
<p>As a first example, consider the <code>foo()</code> function exposed below. When we execute this <code>foo()</code> function, the expression that prints the message “Exiting function …” is getting executed only when the function exits its scope.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb11"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_buffer: [<span class="dv">1024</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_writer = std.fs.File.stdout().writer(&amp;stdout_buffer);</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> stdout = &amp;stdout_writer.interface;</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> foo() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> std.debug.print(</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>        <span class="st">"Exiting function ...</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"Adding some numbers ...</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span>);</span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> x = <span class="dv">2</span> + <span class="dv">2</span>; _ = x;</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"Multiplying ...</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{}</span>);</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> y = <span class="dv">2</span> * <span class="dv">8</span>; _ = y;</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.flush();</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> foo();</span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Adding some numbers ...
Multiplying ...
Exiting function ...</code></pre>
<p>Therefore, we can use <code>defer</code> to declare an expression that is going to be executed when your code exits the current scope. Some programmers like to interpret the phrase “exit of the current scope” as “the end of the current scope”. But this interpretation might not be entirely correct, depending on what you consider as “the end of the current scope”.</p>
<p>I mean, what do you consider as <strong>the end</strong> of the current scope? Is it the closing curly bracket (<code>}</code>) of the scope? Is it when the last expression in the function gets executed? Is it when the function returns to the previous scope? Etc. For example, it would not be correct to interpret the “exit of the current scope” as the closing curly bracket of the scope. Because the function might exit from an earlier position than this closing curly bracket (e.g.&nbsp;an error value was generated at a previous line inside the function; the function reached an earlier return statement; etc.). Anyway, just be careful with this interpretation.</p>
<p>Now, if you remember of what we have discussed in <a href="01-zig-weird.html#sec-blocks" class="quarto-xref"><span>Section 1.7</span></a>, there are multiple structures in the language that create their own separate scopes. For/while loops, if/else statements, functions, normal blocks, etc. This also affects the interpretation of <code>defer</code>. For example, if you use <code>defer</code> inside a for loop, then, the given expression will be executed everytime this specific for loop exits its own scope.</p>
<p>Before we continue, it’s worth emphasizing that the <code>defer</code> keyword is an “unconditional defer”. Which means that the given expression will be executed no matter how the code exits the current scope. For example, your code might exit the current scope because of an error value being generated, or, because of a return statement, or, a break statement, etc.</p>
</section>
<section id="sec-errdefer1" class="level3" data-number="2.1.4">
<h3 data-number="2.1.4" class="anchored" data-anchor-id="sec-errdefer1"><span class="header-section-number">2.1.4</span> The <code>errdefer</code> keyword</h3>
<p>On the previous section, we have discussed the <code>defer</code> keyword, which you can use to register an expression to be executed at the exit of the current scope. But this keyword has a brother, which is the <code>errdefer</code> keyword. While <code>defer</code> is an “unconditional defer”, the <code>errdefer</code> keyword is a “conditional defer”. Which means that the given expression is executed only when you exit the current scope on a very specific circumstance.</p>
<p>In more details, the expression given to <code>errdefer</code> is executed only when an error occurs in the current scope. Therefore, if the function (or for/while loop, if/else statement, etc.) exits the current scope in a normal situation, without errors, the expression given to <code>errdefer</code> is not executed.</p>
<p>This makes the <code>errdefer</code> keyword one of the many tools available in Zig for error handling. In this section, we are more concerned with the control flow aspects around <code>errdefer</code>. But we are going to discuss <code>errdefer</code> later as a error handling tool in <a href="09-error-handling.html#sec-errdefer2" class="quarto-xref"><span>Section 10.2.4</span></a>.</p>
<p>The code example below demonstrates three things:</p>
<ul>
<li>that <code>defer</code> is an “unconditional defer”, because the given expression gets executed regardless of how the function <code>foo()</code> exits its own scope.</li>
<li>that <code>errdefer</code> is executed because the function <code>foo()</code> returned an error value.</li>
<li>that <code>defer</code> and <code>errdefer</code> expressions are executed in a LIFO (<em>last in, first out</em>) order.</li>
</ul>
<div class="cell">
<div class="sourceCode cell-code" id="cb13"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> foo() !<span class="dt">void</span> <span class="op">{</span> <span class="kw">return</span> <span class="kw">error</span>.FooError; <span class="op">}</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> i: <span class="dt">usize</span> = <span class="dv">1</span>;</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">errdefer</span> std.debug.print(<span class="st">"Value of i: {d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> i = <span class="dv">2</span>;</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> foo();</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Value of i: 2
error: FooError
/t.zig:6:5: 0x1037e48 in foo (defer)
    return error.FooError;
    ^</code></pre>
<p>When I say that “defer expressions” are executed in a LIFO order, what I want to say is that the last <code>defer</code> or <code>errdefer</code> expressions in the code are the first ones to be executed. You could also interpret this as: “defer expressions” are executed from bottom to top, or, from last to first.</p>
<p>Therefore, if I change the order of the <code>defer</code> and <code>errdefer</code> expressions, you will notice that the value of <code>i</code> that gets printed to the console changes to 1. This doesn’t mean that the <code>defer</code> expression was not executed in this case. This actually means that the <code>defer</code> expression was executed only after the <code>errdefer</code> expression. The code example below demonstrates this:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb15"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> foo() !<span class="dt">void</span> <span class="op">{</span> <span class="kw">return</span> <span class="kw">error</span>.FooError; <span class="op">}</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> i: <span class="dt">usize</span> = <span class="dv">1</span>;</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> i = <span class="dv">2</span>;</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">errdefer</span> std.debug.print(<span class="st">"Value of i: {d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> foo();</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Value of i: 1
error: FooError
/t.zig:6:5: 0x1037e48 in foo (defer)
    return error.FooError;
    ^</code></pre>
</section>
<section id="for-loops" class="level3" data-number="2.1.5">
<h3 data-number="2.1.5" class="anchored" data-anchor-id="for-loops"><span class="header-section-number">2.1.5</span> For loops</h3>
<p>A loop allows you to execute the same lines of code multiple times, thus, creating a “repetition space” in the execution flow of your program. Loops are particularly useful when we want to replicate the same function (or the same set of commands) over different inputs.</p>
<p>There are different types of loops available in Zig. But the most essential of them all is probably the <em>for loop</em>. A for loop is used to apply the same piece of code over the elements of a slice, or, an array.</p>
<p>For loops in Zig use a syntax that may be unfamiliar to programmers coming from other languages. You start with the <code>for</code> keyword, then, you list the items that you want to iterate over inside a pair of parentheses. Then, inside of a pair of pipes (<code>|</code>) you should declare an identifier that will serve as your iterator, or, the “repetition index of the loop”.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb17"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">for</span> (items) |value| <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// code to execute</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Therefore, instead of using a <code>(value in items)</code> syntax, in Zig, for loops use the syntax <code>(items) |value|</code>. In the example below, you can see that we are looping through the items of the array stored at the object <code>name</code>, and printing to the console the decimal representation of each character in this array.</p>
<p>If we wanted, we could also iterate through a slice (or a portion) of the array, instead of iterating through the entire array stored in the <code>name</code> object. Just use a range selector to select the section you want. For example, I could provide the expression <code>name[0..3]</code> to the for loop, to iterate just through the first 3 elements in the array.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb18"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> name = [_]<span class="dt">u8</span><span class="op">{</span><span class="ch">'P'</span>,<span class="ch">'e'</span>,<span class="ch">'d'</span>,<span class="ch">'r'</span>,<span class="ch">'o'</span><span class="op">}</span>;</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">for</span> (name) |char| <span class="op">{</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{d} | "</span>, .<span class="op">{</span>char<span class="op">}</span>);</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>80 | 101 | 100 | 114 | 111 | </code></pre>
</div>
</div>
<p>In the above example we are using the value itself of each element in the array as our iterator. But there are many situations where we need to use an index instead of the actual values of the items.</p>
<p>You can do that by providing a second set of items to iterate over. More precisely, you provide the range selector <code>0..</code> to the for loop. So, yes, you can use two different iterators at the same time in a for loop in Zig.</p>
<p>But remember from <a href="01-zig-weird.html#sec-assignments" class="quarto-xref"><span>Section 1.4</span></a> that, every object you create in Zig must be used in some way. So if you declare two iterators in your for loop, you must use both iterators inside the for loop body. But if you want to use just the index iterator, and not use the “value iterator”, then, you can discard the value iterator by maching the value items to the underscore character, like in the example below:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb20"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> name = <span class="st">"Pedro"</span>;</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">for</span> (name, <span class="dv">0</span>..) |_, i| <span class="op">{</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{d} | "</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>0 | 1 | 2 | 3 | 4 |</code></pre>
</section>
<section id="while-loops" class="level3" data-number="2.1.6">
<h3 data-number="2.1.6" class="anchored" data-anchor-id="while-loops"><span class="header-section-number">2.1.6</span> While loops</h3>
<p>A while loop is created from the <code>while</code> keyword. A <code>for</code> loop iterates through the items of an array, but a <code>while</code> loop will loop continuously, and infinitely, until a logical test (specified by you) becomes false.</p>
<p>You start with the <code>while</code> keyword, then, you define a logical expression inside a pair of parentheses, and the body of the loop is provided inside a pair of curly braces, like in the example below:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb22"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> i: <span class="dt">u8</span> = <span class="dv">1</span>;</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">while</span> (i &lt; <span class="dv">5</span>) <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{d} | "</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    i += <span class="dv">1</span>;</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1 | 2 | 3 | 4 | </code></pre>
</div>
</div>
<p>You can also specify the increment expression to be used at the beginning of a while loop. To do that, we write the increment expression inside a pair of parentheses after a colon character (<code>:</code>). The code example below demonstrates this other pattern.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb24"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> i: <span class="dt">u8</span> = <span class="dv">1</span>;</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="kw">while</span> (i &lt; <span class="dv">5</span>) : (i += <span class="dv">1</span>) <span class="op">{</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{d} | "</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1 | 2 | 3 | 4 | </code></pre>
</div>
</div>
</section>
<section id="using-break-and-continue" class="level3" data-number="2.1.7">
<h3 data-number="2.1.7" class="anchored" data-anchor-id="using-break-and-continue"><span class="header-section-number">2.1.7</span> Using <code>break</code> and <code>continue</code></h3>
<p>In Zig, you can explicitly stop the execution of a loop, or, jump to the next iteration of the loop, by using the keywords <code>break</code> and <code>continue</code>, respectively. The <code>while</code> loop presented in the next code example is, at first sight, an infinite loop. Because the logical value inside the parenthese will always be equal to <code>true</code>. But what makes this <code>while</code> loop stop when the <code>i</code> object reaches the count 10? It’s the <code>break</code> keyword!</p>
<p>Inside the while loop, we have an if statement that is constantly checking if the <code>i</code> variable is equal to 10. Since we are incrementing the value of <code>i</code> at each iteration of the while loop, this <code>i</code> object will eventually be equal to 10, and when it is, the if statement will execute the <code>break</code> expression, and, as a result, the execution of the while loop is stopped.</p>
<p>Notice the use of the <code>expect()</code> function from the Zig Standard Library after the while loop. This <code>expect()</code> function is an “assert” type of function. This function checks if the logical test provided is equal to true. If so, the function do nothing. Otherwise (i.e., the logical test is equal to false), the function raises an assertion error.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb26"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> i: <span class="dt">usize</span> = <span class="dv">0</span>;</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="kw">while</span> (<span class="cn">true</span>) <span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> (i == <span class="dv">10</span>) <span class="op">{</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">break</span>;</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>    i += <span class="dv">1</span>;</span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> std.testing.expect(i == <span class="dv">10</span>);</span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.print(<span class="st">"Everything worked!"</span>, .<span class="op">{}</span>);</span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>Everything worked!</code></pre>
</div>
</div>
<p>Since this code example was executed successfully by the <code>zig</code> compiler, without raising any errors, we known that, after the execution of the while loop, the <code>i</code> object is equal to 10. Because if it wasn’t equal to 10, an error would have been raised by <code>expect()</code>.</p>
<p>Now, in the next example, we have a use case for the <code>continue</code> keyword. The if statement is constantly checking if the current index is a multiple of 2. If it is, we jump to the next iteration of the loop. Otherwise, the loop just prints the current index to the console.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb28"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ns = [_]<span class="dt">u8</span><span class="op">{</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span><span class="op">}</span>;</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">for</span> (ns) |i| <span class="op">{</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> ((i % <span class="dv">2</span>) == <span class="dv">0</span>) <span class="op">{</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">continue</span>;</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"{d} | "</span>, .<span class="op">{</span>i<span class="op">}</span>);</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a><span class="kw">try</span> stdout.flush();</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1 | 3 | 5 | </code></pre>
</div>
</div>
</section>
</section>
<section id="sec-fun-pars" class="level2" data-number="2.2">
<h2 data-number="2.2" class="anchored" data-anchor-id="sec-fun-pars"><span class="header-section-number">2.2</span> Function parameters are immutable</h2>
<p>We have already discussed a lot of the syntax behind function declarations in <a href="01-zig-weird.html#sec-root-file" class="quarto-xref"><span>Section 1.2.2</span></a> and <a href="01-zig-weird.html#sec-main-file" class="quarto-xref"><span>Section 1.2.3</span></a>. But I want to emphasize a curious fact about function parameters (a.k.a. function arguments) in Zig. In summary, function parameters are immutable in Zig.</p>
<p>Take the code example below, where we declare a simple function that just tries to add some amount to the input integer, and returns the result back. If you look closely at the body of this <code>add2()</code> function, you will notice that we try to save the result back into the <code>x</code> function argument.</p>
<p>In other words, this function not only uses the value that it received through the function argument <code>x</code>, but it also tries to change the value of this function argument, by assigning the addition result into <code>x</code>. However, function arguments in Zig are immutable. You cannot change their values, or, you cannot assign values to them inside the body’s function.</p>
<p>This is the reason why, the code example below does not compile successfully. If you try to compile this code example, you will get a compile error message about “trying to change the value of a immutable (i.e., constant) object”.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb30"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> add2(x: <span class="dt">u32</span>) <span class="dt">u32</span> <span class="op">{</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    x = x + <span class="dv">2</span>;</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> x;</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> y = add2(<span class="dv">4</span>);</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>    std.debug.print(<span class="st">"{d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>y<span class="op">}</span>);</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>t.zig:3:5: error: cannot assign to constant
    x = x + 2;
    ^</code></pre>
<section id="a-free-optimization" class="level3" data-number="2.2.1">
<h3 data-number="2.2.1" class="anchored" data-anchor-id="a-free-optimization"><span class="header-section-number">2.2.1</span> A free optimization</h3>
<p>If a function argument receives as input an object whose data type is any of the primitive types that we have listed in <a href="01-zig-weird.html#sec-primitive-data-types" class="quarto-xref"><span>Section 1.5</span></a>, this object is always passed by value to the function. In other words, this object is copied into the function stack frame.</p>
<p>However, if the input object have a more complex data type, for example, it might be a struct instance, or an array, or an union value, etc., in cases like that, the <code>zig</code> compiler will take the liberty of deciding for you which strategy is best. Thus, the <code>zig</code> compiler will pass your object to the function either by value, or by reference. The compiler will always choose the strategy that is faster for you. This optimization that you get for free is possible only because function arguments are immutable in Zig.</p>
</section>
<section id="how-to-overcome-this-barrier" class="level3" data-number="2.2.2">
<h3 data-number="2.2.2" class="anchored" data-anchor-id="how-to-overcome-this-barrier"><span class="header-section-number">2.2.2</span> How to overcome this barrier</h3>
<p>There are some situations where you might need to change the value of your function argument directly inside the function’s body. This happens more often when we are passing C structs as inputs to Zig functions.</p>
<p>In a situation like this, you can overcome this barrier by using a pointer. In other words, instead of passing a value as input to the argument, you can pass a “pointer to value” instead. You can change the value that the pointer points to, by dereferencing it.</p>
<p>Therefore, if we take our previous <code>add2()</code> example, we can change the value of the function argument <code>x</code> inside the function’s body by marking the <code>x</code> argument as a “pointer to a <code>u32</code> value” (i.e., <code>*u32</code> data type), instead of a <code>u32</code> value. By making it a pointer, we can finally alter the value of this function argument directly inside the body of the <code>add2()</code> function. You can see that the code example below compiles successfully.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb32"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> add2(x: *<span class="dt">u32</span>) <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> d: <span class="dt">u32</span> = <span class="dv">2</span>;</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    x.* = x.* + d;</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> x: <span class="dt">u32</span> = <span class="dv">4</span>;</span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>    add2(&amp;x);</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>    std.debug.print(<span class="st">"Result: {d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>x<span class="op">}</span>);</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Result: 6</code></pre>
<p>Even in this code example above, the <code>x</code> argument is still immutable. Which means that the pointer itself is immutable. Therefore, you cannot change the memory address that it points to. However, you can dereference the pointer to access the value that it points to, and also, to change this value, if you need to.</p>
</section>
</section>
<section id="sec-structs-and-oop" class="level2" data-number="2.3">
<h2 data-number="2.3" class="anchored" data-anchor-id="sec-structs-and-oop"><span class="header-section-number">2.3</span> Structs and OOP</h2>
<p>Zig is a language more closely related to C (which is a procedural language), than it is to C++ or Java (which are object-oriented languages). Because of that, you do not have advanced OOP (Object-Oriented Programming) patterns available in Zig, such as classes, interfaces or class inheritance. Nonetheless, OOP in Zig is still possible by using struct definitions.</p>
<p>With struct definitions, you can create (or define) a new data type in Zig. These struct definitions work the same way as they work in C. You give a name to this new struct (or, to this new data type you are creating), then, you list the data members of this new struct. You can also register functions inside this struct, and they become the methods of this particular struct (or data type), so that, every object that you create with this new type, will always have these methods available and associated with them.</p>
<p>In C++, when we create a new class, we normally have a constructor method (or, a constructor function) which is used to construct (or, to instantiate) every object of this particular class, and we also have a destructor method (or a destructor function), which is the function responsible for destroying every object of this class.</p>
<p>In Zig, we normally declare the constructor and the destructor methods of our structs, by declaring an <code>init()</code> and a <code>deinit()</code> methods inside the struct. This is just a naming convention that you will find across the entire Zig Standard Library. So, in Zig, the <code>init()</code> method of a struct is normally the constructor method of the class represented by this struct. While the <code>deinit()</code> method is the method used for destroying an existing instance of that struct.</p>
<p>The <code>init()</code> and <code>deinit()</code> methods are both used extensively in Zig code, and you will see both of them being used when we talk about allocators in <a href="01-memory.html#sec-allocators" class="quarto-xref"><span>Section 3.3</span></a>. But, as another example, let’s build a simple <code>User</code> struct to represent a user of some sort of system.</p>
<p>If you look at the <code>User</code> struct below, you can see the <code>struct</code> keyword. Notice the data members of this struct: <code>id</code>, <code>name</code> and <code>email</code>. Every data member has its type explicitly annotated, with the colon character (<code>:</code>) syntax that we described earlier in <a href="01-zig-weird.html#sec-root-file" class="quarto-xref"><span>Section 1.2.2</span></a>. But also notice that every line in the struct body that describes a data member, ends with a comma character (<code>,</code>). So every time you declare a data member in your Zig code, always end the line with a comma character, instead of ending it with the traditional semicolon character (<code>;</code>).</p>
<p>Next, we have registered an <code>init()</code> function as a method of this <code>User</code> struct. This <code>init()</code> method is the constructor method that we will use to instantiate every new <code>User</code> object. That is why this <code>init()</code> function returns a new <code>User</code> object as result.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb34"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_buffer: [<span class="dv">1024</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> stdout_writer = std.fs.File.stdout().writer(&amp;stdout_buffer);</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> stdout = &amp;stdout_writer.interface;</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> User = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>    id: <span class="dt">u64</span>,</span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>    name: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>    email: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fn</span> init(id: <span class="dt">u64</span>,</span>
<span id="cb34-11"><a href="#cb34-11" aria-hidden="true" tabindex="-1"></a>            name: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb34-12"><a href="#cb34-12" aria-hidden="true" tabindex="-1"></a>            email: []<span class="kw">const</span> <span class="dt">u8</span>) User <span class="op">{</span></span>
<span id="cb34-13"><a href="#cb34-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-14"><a href="#cb34-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> User <span class="op">{</span></span>
<span id="cb34-15"><a href="#cb34-15" aria-hidden="true" tabindex="-1"></a>            .id = id,</span>
<span id="cb34-16"><a href="#cb34-16" aria-hidden="true" tabindex="-1"></a>            .name = name,</span>
<span id="cb34-17"><a href="#cb34-17" aria-hidden="true" tabindex="-1"></a>            .email = email</span>
<span id="cb34-18"><a href="#cb34-18" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb34-19"><a href="#cb34-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb34-20"><a href="#cb34-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-21"><a href="#cb34-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fn</span> print_name(self: User) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb34-22"><a href="#cb34-22" aria-hidden="true" tabindex="-1"></a>        <span class="kw">try</span> stdout.print(<span class="st">"{s}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>self.name<span class="op">}</span>);</span>
<span id="cb34-23"><a href="#cb34-23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">try</span> stdout.flush();</span>
<span id="cb34-24"><a href="#cb34-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb34-25"><a href="#cb34-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb34-26"><a href="#cb34-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-27"><a href="#cb34-27" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb34-28"><a href="#cb34-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u = User.init(<span class="dv">1</span>, <span class="st">"pedro"</span>, <span class="st">"email@gmail.com"</span>);</span>
<span id="cb34-29"><a href="#cb34-29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> u.print_name();</span>
<span id="cb34-30"><a href="#cb34-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>pedro</code></pre>
</div>
</div>
<section id="the-pub-keyword" class="level3" data-number="2.3.1">
<h3 data-number="2.3.1" class="anchored" data-anchor-id="the-pub-keyword"><span class="header-section-number">2.3.1</span> The <code>pub</code> keyword</h3>
<p>The <code>pub</code> keyword plays an important role in struct declarations, and OOP in Zig. In essence, this keyword is short for “public”, and it makes an item/component available outside of the module where this item/component is declared. In other words, if I don’t apply the <code>pub</code> keyword on something, it means that this “something” is available to be called/used only from within the module where this “something” is declared.</p>
<p>To demonstrate the effect of this keyword let’s focus again on the <code>User</code> struct that we have declared on the previous section. For our example here, let’s suppose that this <code>User</code> struct is declared inside a Zig module named <code>user.zig</code>. If I don’t use the <code>pub</code> keyword on the <code>User</code> struct, it means that I can create an <code>User</code> object, and call it’s methods (<code>print_name()</code> and <code>init()</code>) only from within the module where the <code>User</code> struct is declared, which in this case is the <code>user.zig</code> module.</p>
<p>This is why the previous code example works fine. Because we declare and also use the <code>User</code> struct inside the same module. But problems start to arise when we try to import and call/use this struct from another module. For example, if I create a new module called <code>register.zig</code>, and import the <code>user.zig</code> module into it, and try to annotate any variable with the <code>User</code> type, I get an error from the compiler.</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="co">// register.zig</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> user = <span class="bu">@import</span>(<span class="st">"user.zig"</span>);</span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u: user.User = <span class="cn">undefined</span>;</span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>    _ = u;</span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<pre><code>register.zig:3:18: error: 'User' is not marked 'pub'
    const u: user.User = undefined;
             ~~~~^~~~~
user.zig:3:1: note: declared here
const User = struct {
^~~~~</code></pre>
<p>Therefore, if you want to use something outside of the module where this “something” is declared, you have to mark it with the <code>pub</code> keyword. This “something” can be a module, a struct, a function, an object, etc.</p>
<p>For our example here, if we go back to the <code>user.zig</code> module, and add the <code>pub</code> keyword to the <code>User</code> struct declaration, then, I can successfully compile the <code>register.zig</code> module.</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="co">// user.zig</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="co">// Added the `pub` keyword to `User`</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">const</span> User = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="sourceCode" id="cb39"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="co">// register.zig</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="co">// This works fine now!</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> user = <span class="bu">@import</span>(<span class="st">"user.zig"</span>);</span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u: user.User = <span class="cn">undefined</span>;</span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>    _ = u;</span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<p>Now, what do you think it will happen if I try to actually call from <code>register.zig</code> any of the methods of the <code>User</code> struct? For example, if I try to call the <code>init()</code> method? The answer is: I get a similar error message, warning me that the <code>init()</code> method is not marked as <code>pub</code>, as you can see below:</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> user = <span class="bu">@import</span>(<span class="st">"user.zig"</span>);</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u: user.User = user.User.init(</span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a>        <span class="dv">1</span>, <span class="st">"pedro"</span>, <span class="st">"email@gmail.com"</span></span>
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb40-6"><a href="#cb40-6" aria-hidden="true" tabindex="-1"></a>    _ = u;</span>
<span id="cb40-7"><a href="#cb40-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<pre><code>register.zig:3:35: error: 'init' is not marked 'pub'
    const u: user.User = user.User.init(
                         ~~~~~~~~~^~~~~
user.zig:8:5: note: declared here
    fn init(id: u64,
    ^~~~~~~</code></pre>
<p>Thus, just because we have applied the <code>pub</code> keyword on the struct declaration, this does not make the methods of that struct public as well. If we want to use any method from a struct (such as the <code>init()</code> method) outside of the module where this struct is declared, we have to mark this method with the <code>pub</code> keyword as well.</p>
<p>Going back to the <code>user.zig</code> module, and marking both the <code>init()</code> and <code>print_name()</code> methods with the <code>pub</code> keyword, makes them both available to the outside world, and, as consequence, makes the previous code example work.</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="co">// user.zig</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a><span class="co">// Added the `pub` keyword to `User.init`</span></span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> init(</span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a><span class="co">// Added the `pub` keyword to `User.print_name`</span></span>
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> print_name(self: User) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="sourceCode" id="cb43"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="co">// register.zig</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a><span class="co">// This works fine now!</span></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> user = <span class="bu">@import</span>(<span class="st">"user.zig"</span>);</span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u: user.User = user.User.init(</span>
<span id="cb43-6"><a href="#cb43-6" aria-hidden="true" tabindex="-1"></a>        <span class="dv">1</span>, <span class="st">"pedro"</span>, <span class="st">"email@gmail.com"</span></span>
<span id="cb43-7"><a href="#cb43-7" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb43-8"><a href="#cb43-8" aria-hidden="true" tabindex="-1"></a>    _ = u;</span>
<span id="cb43-9"><a href="#cb43-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</section>
<section id="sec-anonymous-struct-literals" class="level3" data-number="2.3.2">
<h3 data-number="2.3.2" class="anchored" data-anchor-id="sec-anonymous-struct-literals"><span class="header-section-number">2.3.2</span> Anonymous struct literals</h3>
<p>You can declare a struct object as a literal value. When we do that, we normally specify the data type of this struct literal by writing its data type just before the opening curly brace. For example, I could write a struct literal value of the type <code>User</code> that we have defined in the previous section like this:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb44"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> eu = User <span class="op">{</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>    .id = <span class="dv">1</span>,</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>    .name = <span class="st">"Pedro"</span>,</span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>    .email = <span class="st">"someemail@gmail.com"</span></span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a>_ = eu;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>However, in Zig, we can also write an anonymous struct literal. That is, you can write a struct literal, but not specify explicitly the type of this particular struct. An anonymous struct is written by using the syntax <code>.{}</code>. So, we essentially replaced the explicit type of the struct literal with a dot character (<code>.</code>).</p>
<p>As we described in <a href="#sec-type-inference" class="quarto-xref"><span>Section 2.4</span></a>, when you put a dot before a struct literal, the type of this struct literal is automatically inferred by the <code>zig</code> compiler. In essence, the <code>zig</code> compiler will look for some hint of what is the type of that struct. This hint can be the type annotation of a function argument, or the return type annotation of the function that you are using, or the type annotation of an existing object. If the compiler does find such type annotation, it will use this type in your literal struct.</p>
<p>Anonymous structs are very commonly used as inputs to function arguments in Zig. One example that you have seen already constantly, is the <code>print()</code> function from the <code>stdout</code> object. This function takes two arguments. The first argument, is a template string, which should contain string format specifiers in it, which tells how the values provided in the second argument should be printed into the message.</p>
<p>While the second argument is a struct literal that lists the values to be printed into the template message specified in the first argument. You normally want to use an anonymous struct literal here, so that the <code>zig</code> compiler do the job of specifying the type of this particular anonymous struct for you.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb45"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> stdout_buffer: [<span class="dv">1024</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> stdout_writer = std.fs.File.stdout().writer(&amp;stdout_buffer);</span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> stdout = &amp;stdout_writer.interface;</span>
<span id="cb45-6"><a href="#cb45-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.print(<span class="st">"Hello, {s}!</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span><span class="st">"world"</span><span class="op">}</span>);</span>
<span id="cb45-7"><a href="#cb45-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> stdout.flush();</span>
<span id="cb45-8"><a href="#cb45-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hello, world!</code></pre>
</div>
</div>
</section>
<section id="struct-declarations-must-be-constant" class="level3" data-number="2.3.3">
<h3 data-number="2.3.3" class="anchored" data-anchor-id="struct-declarations-must-be-constant"><span class="header-section-number">2.3.3</span> Struct declarations must be constant</h3>
<p>Types in Zig must be <code>const</code> or <code>comptime</code> (we are going to talk more about comptime in <a href="10-stack-project.html#sec-comptime" class="quarto-xref"><span>Section 12.1</span></a>). What this means is that you cannot create a new data type, and mark it as variable with the <code>var</code> keyword. So struct declarations are always constant. You cannot declare a new struct type using the <code>var</code> keyword. It must be <code>const</code>.</p>
<p>In the <code>Vec3</code> example below, this declaration is allowed because I’m using the <code>const</code> keyword to declare this new data type.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb47"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Vec3 = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a>    x: <span class="dt">f64</span>,</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a>    y: <span class="dt">f64</span>,</span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>    z: <span class="dt">f64</span>,</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
</section>
<section id="sec-self-arg" class="level3" data-number="2.3.4">
<h3 data-number="2.3.4" class="anchored" data-anchor-id="sec-self-arg"><span class="header-section-number">2.3.4</span> The <code>self</code> method argument</h3>
<p>In every language that have OOP, when we declare a method of some class or struct, we usually declare this method as a function that has a <code>self</code> argument. This <code>self</code> argument is the reference to the object itself from which the method is being called from.</p>
<p>It’s not mandatory to use this <code>self</code> argument. But why would you not use this <code>self</code> argument? There is no reason to not use it. Because the only way to get access to the data stored in the data members of your struct is to access them through this <code>self</code> argument. If you don’t need to use the data in the data members of your struct inside your method, you very likely don’t need a method. You can just declare this logic as a simple function, outside of your struct declaration.</p>
<p>Take the <code>Vec3</code> struct below. Inside this <code>Vec3</code> struct we declared a method named <code>distance()</code>. This method calculates the distance between two <code>Vec3</code> objects, by following the distance formula in euclidean space. Notice that this <code>distance()</code> method takes two <code>Vec3</code> objects as input, <code>self</code> and <code>other</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb48"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> m = std.math;</span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Vec3 = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a>    x: <span class="dt">f64</span>,</span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a>    y: <span class="dt">f64</span>,</span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a>    z: <span class="dt">f64</span>,</span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> distance(self: Vec3, other: Vec3) <span class="dt">f64</span> <span class="op">{</span></span>
<span id="cb48-9"><a href="#cb48-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> xd = m.pow(<span class="dt">f64</span>, self.x - other.x, <span class="fl">2.0</span>);</span>
<span id="cb48-10"><a href="#cb48-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> yd = m.pow(<span class="dt">f64</span>, self.y - other.y, <span class="fl">2.0</span>);</span>
<span id="cb48-11"><a href="#cb48-11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> zd = m.pow(<span class="dt">f64</span>, self.z - other.z, <span class="fl">2.0</span>);</span>
<span id="cb48-12"><a href="#cb48-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> m.sqrt(xd + yd + zd);</span>
<span id="cb48-13"><a href="#cb48-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb48-14"><a href="#cb48-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>The <code>self</code> argument corresponds to the <code>Vec3</code> object from which this <code>distance()</code> method is being called from. While the <code>other</code> is a separate <code>Vec3</code> object that is given as input to this method. In the example below, the <code>self</code> argument corresponds to the object <code>v1</code>, because the <code>distance()</code> method is being called from the <code>v1</code> object, while the <code>other</code> argument corresponds to the object <code>v2</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb49"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> v1 = Vec3 <span class="op">{</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>    .x = <span class="fl">4.2</span>, .y = <span class="fl">2.4</span>, .z = <span class="fl">0.9</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb49-4"><a href="#cb49-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> v2 = Vec3 <span class="op">{</span></span>
<span id="cb49-5"><a href="#cb49-5" aria-hidden="true" tabindex="-1"></a>    .x = <span class="fl">5.1</span>, .y = <span class="fl">5.6</span>, .z = <span class="fl">1.6</span></span>
<span id="cb49-6"><a href="#cb49-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb49-7"><a href="#cb49-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb49-8"><a href="#cb49-8" aria-hidden="true" tabindex="-1"></a>std.debug.print(</span>
<span id="cb49-9"><a href="#cb49-9" aria-hidden="true" tabindex="-1"></a>    <span class="st">"Distance: {d}</span><span class="sc">\n</span><span class="st">"</span>,</span>
<span id="cb49-10"><a href="#cb49-10" aria-hidden="true" tabindex="-1"></a>    .<span class="op">{</span>v1.distance(v2)<span class="op">}</span></span>
<span id="cb49-11"><a href="#cb49-11" aria-hidden="true" tabindex="-1"></a>);</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Distance: 3.3970575502926055</code></pre>
</section>
<section id="about-the-struct-state" class="level3" data-number="2.3.5">
<h3 data-number="2.3.5" class="anchored" data-anchor-id="about-the-struct-state"><span class="header-section-number">2.3.5</span> About the struct state</h3>
<p>Sometimes you don’t need to care about the state of your struct object. Sometimes, you just need to instantiate and use the objects, without altering their state. You can notice that when you have methods inside your struct declaration that might use the values that are present in the data members, but they do not alter the values in these data members of the struct in anyway.</p>
<p>The <code>Vec3</code> struct that was presented in <a href="#sec-self-arg" class="quarto-xref"><span>Section 2.3.4</span></a> is an example of that. This struct have a single method named <code>distance()</code>, and this method does use the values present in all three data members of the struct (<code>x</code>, <code>y</code> and <code>z</code>). But at the same time, this method does not change the values of these data members at any point.</p>
<p>As a result of that, when we create <code>Vec3</code> objects we usually create them as constant objects, like the <code>v1</code> and <code>v2</code> objects presented in <a href="#sec-self-arg" class="quarto-xref"><span>Section 2.3.4</span></a>. We can create them as variable objects with the <code>var</code> keyword, if we want to. But because the methods of this <code>Vec3</code> struct do not change the state of the objects in any point, it’s unnecessary to mark them as variable objects.</p>
<p>But why? Why am I talking about this here? It’s because the <code>self</code> argument in the methods are affected depending on whether the methods present in a struct change or don’t change the state of the object itself. More specifically, when you have a method in a struct that changes the state of the object (i.e., changes the value of a data member), the <code>self</code> argument in this method must be annotated in a different manner.</p>
<p>As I described in <a href="#sec-self-arg" class="quarto-xref"><span>Section 2.3.4</span></a>, the <code>self</code> argument in methods of a struct is the argument that receives as input the object from which the method was called from. We usually annotate this argument in the methods by writing <code>self</code>, followed by the colon character (<code>:</code>), and the data type of the struct to which the method belongs to (e.g.&nbsp;<code>User</code>, <code>Vec3</code>, etc.).</p>
<p>If we take the <code>Vec3</code> struct that we defined in the previous section as an example, we can see in the <code>distance()</code> method that this <code>self</code> argument is annotated as <code>self: Vec3</code>. Because the state of the <code>Vec3</code> object is never altered by this method.</p>
<p>But what if we do have a method that alters the state of the object, by altering the values of its data members, how should we annotate <code>self</code> in this instance? The answer is: “we should annotate <code>self</code> as a pointer of <code>x</code>, instead of just <code>x</code>”. In other words, you should annotate <code>self</code> as <code>self: *x</code>, instead of annotating it as <code>self: x</code>.</p>
<p>If we create a new method inside the <code>Vec3</code> object that, for example, expands the vector by multiplying its coordinates by a factor of two, then, we need to follow this rule specified in the previous paragraph. The code example below demonstrates this idea:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb51"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb51-2"><a href="#cb51-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> m = std.math;</span>
<span id="cb51-3"><a href="#cb51-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Vec3 = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb51-4"><a href="#cb51-4" aria-hidden="true" tabindex="-1"></a>    x: <span class="dt">f64</span>,</span>
<span id="cb51-5"><a href="#cb51-5" aria-hidden="true" tabindex="-1"></a>    y: <span class="dt">f64</span>,</span>
<span id="cb51-6"><a href="#cb51-6" aria-hidden="true" tabindex="-1"></a>    z: <span class="dt">f64</span>,</span>
<span id="cb51-7"><a href="#cb51-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-8"><a href="#cb51-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> distance(self: Vec3, other: Vec3) <span class="dt">f64</span> <span class="op">{</span></span>
<span id="cb51-9"><a href="#cb51-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> xd = m.pow(<span class="dt">f64</span>, self.x - other.x, <span class="fl">2.0</span>);</span>
<span id="cb51-10"><a href="#cb51-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> yd = m.pow(<span class="dt">f64</span>, self.y - other.y, <span class="fl">2.0</span>);</span>
<span id="cb51-11"><a href="#cb51-11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> zd = m.pow(<span class="dt">f64</span>, self.z - other.z, <span class="fl">2.0</span>);</span>
<span id="cb51-12"><a href="#cb51-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> m.sqrt(xd + yd + zd);</span>
<span id="cb51-13"><a href="#cb51-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb51-14"><a href="#cb51-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-15"><a href="#cb51-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> twice(self: *Vec3) <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb51-16"><a href="#cb51-16" aria-hidden="true" tabindex="-1"></a>        self.x = self.x * <span class="fl">2.0</span>;</span>
<span id="cb51-17"><a href="#cb51-17" aria-hidden="true" tabindex="-1"></a>        self.y = self.y * <span class="fl">2.0</span>;</span>
<span id="cb51-18"><a href="#cb51-18" aria-hidden="true" tabindex="-1"></a>        self.z = self.z * <span class="fl">2.0</span>;</span>
<span id="cb51-19"><a href="#cb51-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb51-20"><a href="#cb51-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Notice in the code example above that we have added a new method to our <code>Vec3</code> struct named <code>twice()</code>. This method doubles the coordinate values of our vector object. In the case of the <code>twice()</code> method, we annotated the <code>self</code> argument as <code>*Vec3</code>, indicating that this argument receives a pointer (or a reference, if you prefer to call it this way) to a <code>Vec3</code> object as input.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb52"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> v3 = Vec3 <span class="op">{</span></span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a>    .x = <span class="fl">4.2</span>, .y = <span class="fl">2.4</span>, .z = <span class="fl">0.9</span></span>
<span id="cb52-3"><a href="#cb52-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb52-4"><a href="#cb52-4" aria-hidden="true" tabindex="-1"></a>v3.twice();</span>
<span id="cb52-5"><a href="#cb52-5" aria-hidden="true" tabindex="-1"></a>std.debug.print(<span class="st">"Doubled: {d}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>v3.x<span class="op">}</span>);</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>Doubled: 8.4</code></pre>
<p>Now, if you change the <code>self</code> argument in this <code>twice()</code> method to <code>self: Vec3</code>, like in the <code>distance()</code> method, you will get the compiler error exposed below as result. Notice that this error message is showing a line from the <code>twice()</code> method body, indicating that you cannot alter the value of the <code>x</code> data member.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb54"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="co">// If we change the function signature of double to:</span></span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> twice(self: Vec3) <span class="dt">void</span> <span class="op">{</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>t.zig:16:13: error: cannot assign to constant
        self.x = self.x * 2.0;
        ~~~~^~</code></pre>
<p>This error message indicates that the <code>x</code> data member belongs to a constant object, and, because of that, it cannot be changed. Ultimately, this error message is telling us that the <code>self</code> argument is constant.</p>
<p>If you take some time, and think hard about this error message, you will understand it. You already have the tools to understand why we are getting this error message. We have talked about it already in <a href="#sec-fun-pars" class="quarto-xref"><span>Section 2.2</span></a>. So remember, every function argument is immutable in Zig, and <code>self</code> is no exception to this rule.</p>
<p>In this example, we marked the <code>v3</code> object as a variable object. But this does not matter. Because it’s not about the input object, it’s about the function argument.</p>
<p>The problem begins when we try to alter the value of <code>self</code> directly, which is a function argument, and, every function argument is immutable by default. You may ask yourself how can we overcome this barrier, and once again, the solution was also discussed in <a href="#sec-fun-pars" class="quarto-xref"><span>Section 2.2</span></a>. We overcome this barrier, by explicitly marking the <code>self</code> argument as a pointer.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>If a method of your <code>x</code> struct alters the state of the object, by changing the value of any data member, then, remember to use <code>self: *x</code>, instead of <code>self: x</code> in the function signature of this method.</p>
</div>
</div>
<p>You could also interpret the content discussed in this section as: “if you need to alter the state of your <code>x</code> struct object in one of its methods, you must explicitly pass the <code>x</code> struct object by reference to the <code>self</code> argument of this method”.</p>
</section>
</section>
<section id="sec-type-inference" class="level2" data-number="2.4">
<h2 data-number="2.4" class="anchored" data-anchor-id="sec-type-inference"><span class="header-section-number">2.4</span> Type inference</h2>
<p>Zig is a strongly typed language. But, there are some situations where you don’t have to explicitly write the type of every single object in your source code, as you would expect from a traditional strongly typed language, such as C and C++.</p>
<p>In some situations, the <code>zig</code> compiler can use type inference to solve the data types for you, easing some of the burden that you carry as a developer. The most common way this happens is through function arguments that receive struct objects as input.</p>
<p>In general, type inference in Zig is done by using the dot character (<code>.</code>). Everytime you see a dot character written before a struct literal, or before an enum value, or something like that, you know that this dot character is playing a special part in this place. More specifically, it’s telling the <code>zig</code> compiler something along the lines of: “Hey! Can you infer the type of this value for me? Please!”. In other words, this dot character is playing a similar role as the <code>auto</code> keyword in C++.</p>
<p>I gave you some examples of this in <a href="#sec-anonymous-struct-literals" class="quarto-xref"><span>Section 2.3.2</span></a>, where we used anonymous struct literals. Anonymous struct literals are, struct literals that use type inference to infer the exact type of this particular struct literal. This type inference is done by looking for some minimal hint of the correct data type to be used. You could say that the <code>zig</code> compiler looks for any neighbouring type annotation that might tell it what the correct type would be.</p>
<p>Another common place where we use type inference in Zig is at switch statements (which we talked about in <a href="#sec-switch" class="quarto-xref"><span>Section 2.1.2</span></a>). I also gave some other examples of type inference in <a href="#sec-switch" class="quarto-xref"><span>Section 2.1.2</span></a>, where we were inferring the data types of enum values listed inside of switch statements (e.g.&nbsp;<code>.DE</code>). But as another example, take a look at this <code>fence()</code> function reproduced below, which comes from the <a href="https://github.com/ziglang/zig/blob/master/lib/std/atomic.zig"><code>atomic.zig</code> module</a><a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> of the Zig Standard Library.</p>
<p>There are a lot of things in this function that we haven’t talked about yet, such as: what <code>comptime</code> means? <code>inline</code>? <code>extern</code>? Let’s just ignore all of these things, and focus solely on the switch statement that is inside this function.</p>
<p>We can see that this switch statement uses the <code>order</code> object as input. This <code>order</code> object is one of the inputs of this <code>fence()</code> function, and we can see in the type annotation, that this object is of type <code>AtomicOrder</code>. We can also see a bunch of values inside the switch statements that begin with a dot character, such as <code>.release</code> and <code>.acquire</code>.</p>
<p>Because these weird values contain a dot character before them, we are asking the <code>zig</code> compiler to infer the types of these values inside the switch statement. Then, the <code>zig</code> compiler is looking into the current context where these values are being used, and trying to infer the types of these values.</p>
<p>Since they are being used inside a switch statement, the <code>zig</code> compiler looks into the type of the input object given to the switch statement, which is the <code>order</code> object in this case. Because this object have type <code>AtomicOrder</code>, the <code>zig</code> compiler infers that these values are data members from this type <code>AtomicOrder</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb56"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">inline</span> <span class="kw">fn</span> fence(self: *Self, <span class="kw">comptime</span> order: AtomicOrder) <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// many lines of code ...</span></span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> (builtin.sanitize_thread) <span class="op">{</span></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> tsan = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">extern</span> <span class="st">"c"</span> <span class="kw">fn</span> __tsan_acquire(addr: *anyopaque) <span class="dt">void</span>;</span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">extern</span> <span class="st">"c"</span> <span class="kw">fn</span> __tsan_release(addr: *anyopaque) <span class="dt">void</span>;</span>
<span id="cb56-7"><a href="#cb56-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb56-8"><a href="#cb56-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-9"><a href="#cb56-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> addr: *anyopaque = self;</span>
<span id="cb56-10"><a href="#cb56-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">switch</span> (order) <span class="op">{</span></span>
<span id="cb56-11"><a href="#cb56-11" aria-hidden="true" tabindex="-1"></a>            .unordered, .monotonic =&gt; <span class="bu">@compileError</span>(</span>
<span id="cb56-12"><a href="#cb56-12" aria-hidden="true" tabindex="-1"></a>                <span class="bu">@tagName</span>(order)</span>
<span id="cb56-13"><a href="#cb56-13" aria-hidden="true" tabindex="-1"></a>                ++ <span class="st">" only applies to atomic loads and stores"</span></span>
<span id="cb56-14"><a href="#cb56-14" aria-hidden="true" tabindex="-1"></a>            ),</span>
<span id="cb56-15"><a href="#cb56-15" aria-hidden="true" tabindex="-1"></a>            .acquire =&gt; tsan.__tsan_acquire(addr),</span>
<span id="cb56-16"><a href="#cb56-16" aria-hidden="true" tabindex="-1"></a>            .release =&gt; tsan.__tsan_release(addr),</span>
<span id="cb56-17"><a href="#cb56-17" aria-hidden="true" tabindex="-1"></a>            .acq_rel, .seq_cst =&gt; <span class="op">{</span></span>
<span id="cb56-18"><a href="#cb56-18" aria-hidden="true" tabindex="-1"></a>                tsan.__tsan_acquire(addr);</span>
<span id="cb56-19"><a href="#cb56-19" aria-hidden="true" tabindex="-1"></a>                tsan.__tsan_release(addr);</span>
<span id="cb56-20"><a href="#cb56-20" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span>,</span>
<span id="cb56-21"><a href="#cb56-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb56-22"><a href="#cb56-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb56-23"><a href="#cb56-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-24"><a href="#cb56-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="bu">@fence</span>(order);</span>
<span id="cb56-25"><a href="#cb56-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>This is how basic type inference is done in Zig. If we didn’t use the dot character before the values inside this switch statement, then, we would be forced to explicitly write the data types of these values. For example, instead of writing <code>.release</code> we would have to write <code>AtomicOrder.release</code>. We would have to do this for every single value in this switch statement, and this is a lot of work. That is why type inference is commonly used on switch statements in Zig.</p>
</section>
<section id="sec-type-cast" class="level2" data-number="2.5">
<h2 data-number="2.5" class="anchored" data-anchor-id="sec-type-cast"><span class="header-section-number">2.5</span> Type casting</h2>
<p>In this section, I want to discuss type casting (or, type conversion) with you. We use type casting when we have an object of type “x”, and we want to convert it into an object of type “y”, i.e., we want to change the data type of the object.</p>
<p>Most languages have a formal way to perform type casting. In Rust for example, we normally use the keyword <code>as</code>, and in C, we normally use the type casting syntax, e.g.&nbsp;<code>(int) x</code>. In Zig, we use the <code>@as()</code> built-in function to cast an object of type “x”, into an object of type “y”.</p>
<p>This <code>@as()</code> function is the preferred way to perform type conversion (or type casting) in Zig. Because it’s explicit, and, it also performs the casting only if it is unambiguous and safe. To use this function, you just provide the target data type in the first argument, and, the object that you want cast as the second argument.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb57"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> expect = std.testing.expect;</span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a><span class="kw">test</span> <span class="op">{</span></span>
<span id="cb57-4"><a href="#cb57-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> x: <span class="dt">usize</span> = <span class="dv">500</span>;</span>
<span id="cb57-5"><a href="#cb57-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> y = <span class="bu">@as</span>(<span class="dt">u32</span>, x);</span>
<span id="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> expect(<span class="bu">@TypeOf</span>(y) == <span class="dt">u32</span>);</span>
<span id="cb57-7"><a href="#cb57-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1/1 file11db7feb191f.test_0...OKAll 1 tests passed
  d.</code></pre>
</div>
</div>
<p>This is the general way to perform type casting in Zig. But remember, <code>@as()</code> works only when casting is unambiguous and safe. There are many situations where these assumptions do not hold. For example,</p>
<p>when casting an integer value into a float value, or vice-versa, it’s not clear to the compiler how to perform this conversion safely.</p>
<p>Therefore, we need to use specialized “casting functions” in such situations. For example, if you want to cast an integer value into a float value, then, you should use the <code>@floatFromInt()</code> function. In the inverse scenario, you should use the <code>@intFromFloat()</code> function.</p>
<p>In these functions, you just provide the object that you want to cast as input. Then, the target data type of the “type casting operation” is determined by the type annotation of the object where you are saving the results. In the example below, we are casting the object <code>x</code> into a value of type <code>f32</code>, because the object <code>y</code>, which is where we are saving the results, is annotated as an object of type <code>f32</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb59"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> expect = std.testing.expect;</span>
<span id="cb59-3"><a href="#cb59-3" aria-hidden="true" tabindex="-1"></a><span class="kw">test</span> <span class="op">{</span></span>
<span id="cb59-4"><a href="#cb59-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> x: <span class="dt">usize</span> = <span class="dv">565</span>;</span>
<span id="cb59-5"><a href="#cb59-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> y: <span class="dt">f32</span> = <span class="bu">@floatFromInt</span>(x);</span>
<span id="cb59-6"><a href="#cb59-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> expect(<span class="bu">@TypeOf</span>(y) == <span class="dt">f32</span>);</span>
<span id="cb59-7"><a href="#cb59-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1/1 file11db2dc629dd.test_0...OKAll 1 tests passed
  d.</code></pre>
</div>
</div>
<p>Another built-in function that is very useful when performing type casting operations is <code>@ptrCast()</code>. In essence, we use the <code>@as()</code> built-in function when we want to explicit convert (or cast) a Zig value/object from a type “x” to a type “y”, etc. However, pointers (we are going to discuss pointers in more depth in <a href="05-pointers.html" class="quarto-xref"><span>Chapter 6</span></a>) are a special type of object in Zig, i.e., they are treated differently from “normal objects”.</p>
<p>Everytime a pointer is involved in some “type casting operation” in Zig, the <code>@ptrCast()</code> function is used. This function works similarly to <code>@floatFromInt()</code>. You just provide the pointer object that you want to cast as input to this function, and the target data type is, once again, determined by the type annotation of the object where the results are being stored.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb61"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> expect = std.testing.expect;</span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true" tabindex="-1"></a><span class="kw">test</span> <span class="op">{</span></span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> bytes <span class="kw">align</span>(<span class="bu">@alignOf</span>(<span class="dt">u32</span>)) = [_]<span class="dt">u8</span><span class="op">{</span></span>
<span id="cb61-5"><a href="#cb61-5" aria-hidden="true" tabindex="-1"></a>        <span class="bn">0x12</span>, <span class="bn">0x12</span>, <span class="bn">0x12</span>, <span class="bn">0x12</span></span>
<span id="cb61-6"><a href="#cb61-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb61-7"><a href="#cb61-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> u32_ptr: *<span class="kw">const</span> <span class="dt">u32</span> = <span class="bu">@ptrCast</span>(&amp;bytes);</span>
<span id="cb61-8"><a href="#cb61-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> expect(<span class="bu">@TypeOf</span>(u32_ptr) == *<span class="kw">const</span> <span class="dt">u32</span>);</span>
<span id="cb61-9"><a href="#cb61-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>1/1 file11db73036c39.test_0...OKAll 1 tests passed
  d.</code></pre>
</div>
</div>
</section>
<section id="modules" class="level2" data-number="2.6">
<h2 data-number="2.6" class="anchored" data-anchor-id="modules"><span class="header-section-number">2.6</span> Modules</h2>
<p>We already talked about what modules are, and also, how to import other modules into your current module via <em>import statements</em>. Every Zig module (i.e., a <code>.zig</code> file) that you write in your project is internally stored as a struct object. Take the line exposed below as an example. In this line we are importing the Zig Standard Library into our current module.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb63"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>When we want to access the functions and objects from the standard library, we are basically accessing the data members of the struct stored in the <code>std</code> object. That is why we use the same syntax that we use in normal structs, with the dot operator (<code>.</code>) to access the data members and methods of the struct.</p>
<p>When this “import statement” gets executed, the result of this expression is a struct object that contains the Zig Standard Library modules, global variables, functions, etc. And this struct object gets saved (or stored) inside the constant object named <code>std</code>.</p>
<p>Take the <a href="https://github.com/kprotty/zap/blob/blog/src/thread_pool.zig"><code>thread_pool.zig</code> module from the project <code>zap</code></a><a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a> as an example. This module is written as if it was a big struct. That is why we have a top-level and public <code>init()</code> method written in this module. The idea is that all top-level functions written in this module are methods from the struct, and all top-level objects and struct declarations are data members of this struct. The module is the struct itself.</p>
<p>So you would import and use this module by doing something like this:</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb64"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ThreadPool = <span class="bu">@import</span>(<span class="st">"thread_pool.zig"</span>);</span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> num_cpus = std.Thread.getCpuCount()</span>
<span id="cb64-4"><a href="#cb64-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">catch</span> <span class="bu">@panic</span>(<span class="st">"failed to get cpu core count"</span>);</span>
<span id="cb64-5"><a href="#cb64-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> num_threads = std.math.cast(<span class="dt">u16</span>, num_cpus)</span>
<span id="cb64-6"><a href="#cb64-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">catch</span> std.math.maxInt(<span class="dt">u16</span>);</span>
<span id="cb64-7"><a href="#cb64-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> pool = ThreadPool.init(</span>
<span id="cb64-8"><a href="#cb64-8" aria-hidden="true" tabindex="-1"></a>    .<span class="op">{</span> .max_threads = num_threads <span class="op">}</span></span>
<span id="cb64-9"><a href="#cb64-9" aria-hidden="true" tabindex="-1"></a>);</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>


</section>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr>
<ol>
<li id="fn1"><p><a href="https://github.com/ziglang/zig/blob/master/lib/std/debug.zig" class="uri">https://github.com/ziglang/zig/blob/master/lib/std/debug.zig</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p><a href="https://github.com/ziglang/zig/blob/master/lib/std/atomic.zig" class="uri">https://github.com/ziglang/zig/blob/master/lib/std/atomic.zig</a>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p><a href="https://github.com/kprotty/zap/blob/blog/src/thread_pool.zig" class="uri">https://github.com/kprotty/zap/blob/blog/src/thread_pool.zig</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>

</main> <!-- /main -->
<script id="quarto-html-after-body" type="application/javascript">
  window.document.addEventListener("DOMContentLoaded", function (event) {
    // Ensure there is a toggle, if there isn't float one in the top right
    if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
      const a = window.document.createElement('a');
      a.classList.add('top-right');
      a.classList.add('quarto-color-scheme-toggle');
      a.href = "";
      a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
      const i = window.document.createElement("i");
      i.classList.add('bi');
      a.appendChild(i);
      window.document.body.appendChild(a);
    }
    setColorSchemeToggle(hasAlternateSentinel())
    const icon = "";
    const anchorJS = new window.AnchorJS();
    anchorJS.options = {
      placement: 'right',
      icon: icon
    };
    anchorJS.add('.anchored');
    const isCodeAnnotation = (el) => {
      for (const clz of el.classList) {
        if (clz.startsWith('code-annotation-')) {                     
          return true;
        }
      }
      return false;
    }
    const onCopySuccess = function(e) {
      // button target
      const button = e.trigger;
      // don't keep focus
      button.blur();
      // flash "checked"
      button.classList.add('code-copy-button-checked');
      var currentTitle = button.getAttribute("title");
      button.setAttribute("title", "Copied!");
      let tooltip;
      if (window.bootstrap) {
        button.setAttribute("data-bs-toggle", "tooltip");
        button.setAttribute("data-bs-placement", "left");
        button.setAttribute("data-bs-title", "Copied!");
        tooltip = new bootstrap.Tooltip(button, 
          { trigger: "manual", 
            customClass: "code-copy-button-tooltip",
            offset: [0, -8]});
        tooltip.show();    
      }
      setTimeout(function() {
        if (tooltip) {
          tooltip.hide();
          button.removeAttribute("data-bs-title");
          button.removeAttribute("data-bs-toggle");
          button.removeAttribute("data-bs-placement");
        }
        button.setAttribute("title", currentTitle);
        button.classList.remove('code-copy-button-checked');
      }, 1000);
      // clear code selection
      e.clearSelection();
    }
    const getTextToCopy = function(trigger) {
        const codeEl = trigger.previousElementSibling.cloneNode(true);
        for (const childEl of codeEl.children) {
          if (isCodeAnnotation(childEl)) {
            childEl.remove();
          }
        }
        return codeEl.innerText;
    }
    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
      text: getTextToCopy
    });
    clipboard.on('success', onCopySuccess);
    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
        text: getTextToCopy,
        container: window.document.getElementById('quarto-embedded-source-code-modal')
      });
      clipboardModal.on('success', onCopySuccess);
    }
      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
      var mailtoRegex = new RegExp(/^mailto:/);
        var filterRegex = new RegExp('/' + window.location.host + '/');
      var isInternal = (href) => {
          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
      }
      // Inspect non-navigation links and adorn them if external
     var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
      for (var i=0; i<links.length; i++) {
        const link = links[i];
        if (!isInternal(link.href)) {
          // undo the damage that might have been done by quarto-nav.js in the case of
          // links that we want to consider external
          if (link.dataset.originalHref !== undefined) {
            link.href = link.dataset.originalHref;
          }
        }
      }
    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
      const config = {
        allowHTML: true,
        maxWidth: 500,
        delay: 100,
        arrow: false,
        appendTo: function(el) {
            return el.parentElement;
        },
        interactive: true,
        interactiveBorder: 10,
        theme: 'quarto',
        placement: 'bottom-start',
      };
      if (contentFn) {
        config.content = contentFn;
      }
      if (onTriggerFn) {
        config.onTrigger = onTriggerFn;
      }
      if (onUntriggerFn) {
        config.onUntrigger = onUntriggerFn;
      }
      window.tippy(el, config); 
    }
    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
    for (var i=0; i<noterefs.length; i++) {
      const ref = noterefs[i];
      tippyHover(ref, function() {
        // use id or data attribute instead here
        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
        try { href = new URL(href).hash; } catch {}
        const id = href.replace(/^#\/?/, "");
        const note = window.document.getElementById(id);
        if (note) {
          return note.innerHTML;
        } else {
          return "";
        }
      });
    }
    const xrefs = window.document.querySelectorAll('a.quarto-xref');
    const processXRef = (id, note) => {
      // Strip column container classes
      const stripColumnClz = (el) => {
        el.classList.remove("page-full", "page-columns");
        if (el.children) {
          for (const child of el.children) {
            stripColumnClz(child);
          }
        }
      }
      stripColumnClz(note)
      if (id === null || id.startsWith('sec-')) {
        // Special case sections, only their first couple elements
        const container = document.createElement("div");
        if (note.children && note.children.length > 2) {
          container.appendChild(note.children[0].cloneNode(true));
          for (let i = 1; i < note.children.length; i++) {
            const child = note.children[i];
            if (child.tagName === "P" && child.innerText === "") {
              continue;
            } else {
              container.appendChild(child.cloneNode(true));
              break;
            }
          }
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(container);
          }
          return container.innerHTML
        } else {
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(note);
          }
          return note.innerHTML;
        }
      } else {
        // Remove any anchor links if they are present
        const anchorLink = note.querySelector('a.anchorjs-link');
        if (anchorLink) {
          anchorLink.remove();
        }
        if (window.Quarto?.typesetMath) {
          window.Quarto.typesetMath(note);
        }
        if (note.classList.contains("callout")) {
          return note.outerHTML;
        } else {
          return note.innerHTML;
        }
      }
    }
    for (var i=0; i<xrefs.length; i++) {
      const xref = xrefs[i];
      tippyHover(xref, undefined, function(instance) {
        instance.disable();
        let url = xref.getAttribute('href');
        let hash = undefined; 
        if (url.startsWith('#')) {
          hash = url;
        } else {
          try { hash = new URL(url).hash; } catch {}
        }
        if (hash) {
          const id = hash.replace(/^#\/?/, "");
          const note = window.document.getElementById(id);
          if (note !== null) {
            try {
              const html = processXRef(id, note.cloneNode(true));
              instance.setContent(html);
            } finally {
              instance.enable();
              instance.show();
            }
          } else {
            // See if we can fetch this
            fetch(url.split('#')[0])
            .then(res => res.text())
            .then(html => {
              const parser = new DOMParser();
              const htmlDoc = parser.parseFromString(html, "text/html");
              const note = htmlDoc.getElementById(id);
              if (note !== null) {
                const html = processXRef(id, note);
                instance.setContent(html);
              } 
            }).finally(() => {
              instance.enable();
              instance.show();
            });
          }
        } else {
          // See if we can fetch a full url (with no hash to target)
          // This is a special case and we should probably do some content thinning / targeting
          fetch(url)
          .then(res => res.text())
          .then(html => {
            const parser = new DOMParser();
            const htmlDoc = parser.parseFromString(html, "text/html");
            const note = htmlDoc.querySelector('main.content');
            if (note !== null) {
              // This should only happen for chapter cross references
              // (since there is no id in the URL)
              // remove the first header
              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
                note.children[0].remove();
              }
              const html = processXRef(null, note);
              instance.setContent(html);
            } 
          }).finally(() => {
            instance.enable();
            instance.show();
          });
        }
      }, function(instance) {
      });
    }
        let selectedAnnoteEl;
        const selectorForAnnotation = ( cell, annotation) => {
          let cellAttr = 'data-code-cell="' + cell + '"';
          let lineAttr = 'data-code-annotation="' +  annotation + '"';
          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
          return selector;
        }
        const selectCodeLines = (annoteEl) => {
          const doc = window.document;
          const targetCell = annoteEl.getAttribute("data-target-cell");
          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
          const lineIds = lines.map((line) => {
            return targetCell + "-" + line;
          })
          let top = null;
          let height = null;
          let parent = null;
          if (lineIds.length > 0) {
              //compute the position of the single el (top and bottom and make a div)
              const el = window.document.getElementById(lineIds[0]);
              top = el.offsetTop;
              height = el.offsetHeight;
              parent = el.parentElement.parentElement;
            if (lineIds.length > 1) {
              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
              height = bottom - top;
            }
            if (top !== null && height !== null && parent !== null) {
              // cook up a div (if necessary) and position it 
              let div = window.document.getElementById("code-annotation-line-highlight");
              if (div === null) {
                div = window.document.createElement("div");
                div.setAttribute("id", "code-annotation-line-highlight");
                div.style.position = 'absolute';
                parent.appendChild(div);
              }
              div.style.top = top - 2 + "px";
              div.style.height = height + 4 + "px";
              div.style.left = 0;
              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
              if (gutterDiv === null) {
                gutterDiv = window.document.createElement("div");
                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
                gutterDiv.style.position = 'absolute';
                const codeCell = window.document.getElementById(targetCell);
                const gutter = codeCell.querySelector('.code-annotation-gutter');
                gutter.appendChild(gutterDiv);
              }
              gutterDiv.style.top = top - 2 + "px";
              gutterDiv.style.height = height + 4 + "px";
            }
            selectedAnnoteEl = annoteEl;
          }
        };
        const unselectCodeLines = () => {
          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
          elementsIds.forEach((elId) => {
            const div = window.document.getElementById(elId);
            if (div) {
              div.remove();
            }
          });
          selectedAnnoteEl = undefined;
        };
          // Handle positioning of the toggle
      window.addEventListener(
        "resize",
        throttle(() => {
          elRect = undefined;
          if (selectedAnnoteEl) {
            selectCodeLines(selectedAnnoteEl);
          }
        }, 10)
      );
      function throttle(fn, ms) {
      let throttle = false;
      let timer;
        return (...args) => {
          if(!throttle) { // first call gets through
              fn.apply(this, args);
              throttle = true;
          } else { // all the others get throttled
              if(timer) clearTimeout(timer); // cancel #2
              timer = setTimeout(() => {
                fn.apply(this, args);
                timer = throttle = false;
              }, ms);
          }
        };
      }
        // Attach click handler to the DT
        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
        for (const annoteDlNode of annoteDls) {
          annoteDlNode.addEventListener('click', (event) => {
            const clickedEl = event.target;
            if (clickedEl !== selectedAnnoteEl) {
              unselectCodeLines();
              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
              if (activeEl) {
                activeEl.classList.remove('code-annotation-active');
              }
              selectCodeLines(clickedEl);
              clickedEl.classList.add('code-annotation-active');
            } else {
              // Unselect the line
              unselectCodeLines();
              clickedEl.classList.remove('code-annotation-active');
            }
          });
        }
    const findCites = (el) => {
      const parentEl = el.parentElement;
      if (parentEl) {
        const cites = parentEl.dataset.cites;
        if (cites) {
          return {
            el,
            cites: cites.split(' ')
          };
        } else {
          return findCites(el.parentElement)
        }
      } else {
        return undefined;
      }
    };
    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
    for (var i=0; i<bibliorefs.length; i++) {
      const ref = bibliorefs[i];
      const citeInfo = findCites(ref);
      if (citeInfo) {
        tippyHover(citeInfo.el, function() {
          var popup = window.document.createElement('div');
          citeInfo.cites.forEach(function(cite) {
            var citeDiv = window.document.createElement('div');
            citeDiv.classList.add('hanging-indent');
            citeDiv.classList.add('csl-entry');
            var biblioDiv = window.document.getElementById('ref-' + cite);
            if (biblioDiv) {
              citeDiv.innerHTML = biblioDiv.innerHTML;
            }
            popup.appendChild(citeDiv);
          });
          return popup.innerHTML;
        });
      }
    }
  });
  </script>
<nav class="page-navigation">
  <div class="nav-page nav-page-previous">
      <a href="../Chapters/01-zig-weird.html" class="pagination-link" aria-label="Introducing Zig">
        <i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">1</span>&nbsp; <span class="chapter-title">Introducing Zig</span></span>
      </a>          
  </div>
  <div class="nav-page nav-page-next">
      <a href="../Chapters/01-memory.html" class="pagination-link" aria-label="Memory and Allocators">
        <span class="nav-page-text"><span class="chapter-number">3</span>&nbsp; <span class="chapter-title">Memory and Allocators</span></span> <i class="bi bi-arrow-right-short"></i>
      </a>
  </div>
</nav>
</div> <!-- /content -->




</body></html>